using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Workflow.Activities;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using MbUnit.Framework;

namespace DP.Sharepoint.Workflow.Tests.ForTesting
{
    public class WorkflowBaseFixture
    {
        private WorkflowRuntimeManager _manager;

        public WorkflowRuntimeManager Manager
        {
            get { return _manager; }
        }

        public ExternalDataExchangeService ExternalDataService
        {
            get { return _dataService; }
        }

        private ExternalDataExchangeService _dataService;

        [TestFixtureSetUp]
        public void FixutreSetUp()
        {
            _manager = new WorkflowRuntimeManager(new WorkflowRuntime("WorkflowRuntime"));

            _manager.MessageEvent += delegate(Object sender, WorkflowLogEventArgs e) { Trace.WriteLine(e.Message); };

            _dataService = new ExternalDataExchangeService();
            _manager.WorkflowRuntime.AddService(_dataService);
            //_manager.WorkflowRuntime.AddService(new FilePersistenceService(true));

            AddServices(_manager.WorkflowRuntime);

        }

        [TestFixtureTearDown]
        public void TestFixtureTearDown()
        {
            if (_manager != null)
            {
                _manager.Dispose();
            }
        }

        [SetUp]
        public virtual void TestSetup()
        {
            _manager.WorkflowRuntime.StartRuntime();
        }

        [TearDown]
        public virtual void TestTearDown()
        {
            _manager.ClearAllWorkflows();
            _manager.WorkflowRuntime.StopRuntime();
        }

        public virtual void AddServices(WorkflowRuntime runtime)
        {
        }

        public Guid RunWorkflows(Type workflowType, Dictionary<string, Object> wfArguments,
                                 int WaitFor)
        {
            return Manager.CreateStartWorkflow(workflowType, wfArguments);
        }


        protected static void AddActivityToWorkflowInstance(WorkflowInstance instance, Activity activity)
        {
            WorkflowChanges wfChanges = new WorkflowChanges(instance.GetWorkflowDefinition());

            if (wfChanges.TransientWorkflow == null)
            {
                throw new NullReferenceException("this workflow cannot be changed [this.TransientWorkflow] returned null");
            }

            wfChanges.TransientWorkflow.Activities.Add(activity);

            instance.ApplyWorkflowChanges(wfChanges);
        }



        protected void RunWorkflows(int timeout)
        {
            foreach (Guid workflowId in Manager.Workflows.Keys)
            {
                Manager.RunWorkflow(workflowId, timeout);
            }
        }


        protected void AddExternalDataService(object service)
        {
            _dataService.AddService(service);
        }


    }
}